﻿using System;
using System.Configuration;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using Medianamik.Core;
using Medianamik.Core.Configuration;
using Medianamik.Core.Profile;
using Medianamik.Core.Sugar;
using Medianamik.Globalization;
using Telerik.Web.UI;
using System.Linq;

namespace Medianamik.UI.Controls
{
    public abstract class BaseEditor : BaseMedianamikControl
    {
        protected BaseEditor(MedianamikConfigSection config)
        {
            Config = config;
            IsMultiLingual = true;
        }
        protected BaseEditor()
            :this((MedianamikConfigSection)ConfigurationManager.GetSection(ConfigurationSectionName.MEDIANAMIK))
        {
            
        }

        //http://www.telerik.com/community/forums/aspnet-ajax/editor/resize-manager-dialog-windows.aspx
        //http://www.telerik.com/support/kb/aspnet-ajax/editor/setting-dialog-pop-up-position.aspx
        //protected override void OnInit(EventArgs e)
        //{
        //    base.OnInit(e);
        //    Page.PreRenderComplete += Page_PreRenderComplete;
        //}

        //void Page_PreRenderComplete(object sender, EventArgs e)
        //{
        //    var documentManager = editor.GetDialogDefinition("DocumentManager");
        //    documentManager.Height = Unit.Pixel(1500);
        //    documentManager.Width = Unit.Pixel(1500);

        //    var imageManager = editor.GetDialogDefinition("ImageManager");
        //    imageManager.Height = Unit.Pixel(1500);
        //    imageManager.Width = Unit.Pixel(1500);
        //}

        protected RadEditor editor = new RadEditor();
        protected string _cssFilePath = "";
        protected MedianamikConfigSection Config;

        protected internal RadEditor RadEditor
        {
            get
            {
                return editor;
            }
        }

        protected override bool WrapContentInParagraph
        {
            get
            {
                return false;
            }
        }

        protected virtual string ScriptPath
        {
            get
            {
                return "Scripts.Editor.js";
            }
        }

        public int MaxUploadFileSize
        {
            get
            {
                return Config.EditorMaxUploadFileSize;
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            if (!DesignMode)
            {
                var sm = ScriptManager.GetCurrent(Page);
                if (sm == null)
                {
                    throw new Exception("A ScriptManager control must exist on the current page.");
                }
                //On ajoute les references aux scripts du RadEditor pour s'assurer
                //qu'ils sont chargés et exécutés avant le script js de l'éditeur 
                var requiredReferences = ((IScriptControl) editor).GetScriptReferences();
                foreach(var @ref in requiredReferences )
                {
                    sm.Scripts.Add(@ref);
                }
                Resources.RegisterScript(ScriptPath, Page, typeof(BaseEditor).Assembly);
            }
        }

        protected void SetDialogSearchPatterns(FileManagerDialogConfiguration dialog, string userDefinedExtension, params string[] defaultExtensions)
        {
            var extensions = userDefinedExtension.Length > 0 ?
                userDefinedExtension.Split(',').Concat(defaultExtensions).ToArray() :
                defaultExtensions;

            if (extensions.Count() > 0)
                dialog.SearchPatterns = extensions;
        }

        protected void SetDialogPaths(FileManagerDialogConfiguration dialog, string path)
        {
            dialog.ViewPaths = new[] { path };
            dialog.UploadPaths = new[] { path };
            dialog.DeletePaths = new[] { path };
            dialog.MaxUploadFileSize = MaxUploadFileSize;
        }

        protected static void SetEditorToolbarMode(RadEditor editor)
        {
            if (HttpContext.Current != null)
            {
                var toolbarMode = (EditorToolbarMode)((UserProfile)HttpContext.Current.Profile).EditorToolbarMode;
                switch (toolbarMode)
                {
                    case EditorToolbarMode.Default:
                    case EditorToolbarMode.Floating:
                    case EditorToolbarMode.PageTop:
                    case EditorToolbarMode.ShowOnFocus:
                        editor.ToolbarMode = toolbarMode;
                        break;
                    default: editor.ToolbarMode = EditorToolbarMode.Default; break;
                }
            }
        }

        protected void AddParagraph(string tagName, string nameKey)
        {
            string name = "<" + tagName + ">" + Translator.Translate("Medianamik_ContentManagement", nameKey) + "</" + tagName + ">";
            var p = new EditorParagraph("<" + tagName + ">", name);
            editor.Paragraphs.Add(p);
        }

        protected void AddParagraphs(string resourceName)
        {
            var paragraphXml = Resources.GetResourceText(resourceName, Assembly.GetExecutingAssembly());
            var paragraphDoc = new XmlDocument();
            paragraphDoc.LoadXml(paragraphXml);
            var root = paragraphDoc.DocumentElement;
            if (root != null)
            {
                editor.Paragraphs.Clear();
                foreach (XmlNode elem in root.SelectNodes("paragraph"))
                {
                    AddParagraph(elem.SelectSingleNode("tag").InnerText, elem.SelectSingleNode("name").InnerText);
                }
            }
        }

        protected abstract string GetEditorXml();

        public override Type TypeOfValue
        {
            get { return typeof(string); }
        }

        public override object GetValue()
        {

            EnsureChildControls();

            return CleanContent(editor.Content);
        }

        public override void SetValue(object value)
        {
            EnsureChildControls();
            editor.Content = value.ToString();
        }

        protected override WebControl SizedControl
        {
            get
            {
                EnsureChildControls();
                return editor;
            }
        }

        protected virtual string CleanContent(string content)
        {
            var result = "";

            //Si le contenu ne contient que du HTML, on retourne vide.
            if (!Regex.IsMatch(content, @"<img|<object|<embed"))
                if (Regex.Replace(content, @"(</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>)|\s", string.Empty).Length == 0)
                    return result;

            //return Regex.Replace(content, "(?<TagStart>href=\"?)(?<Junk>.*)(?<Token>.@[({]?(0x)?[0-9a-fA-F]{8}([-,]?(0x)?[0-9a-fA-F]{4}){2}((-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{12})|(,\\{0x[0-9a-fA-F]{2}(,0x[0-9a-fA-F]{2}){7}\\}))[)}]?.@)",
            //    "${TagStart}${Token}");

            result = Regex.Replace(content, @"(?<TagStart>href=\""?)(?<crap>[^\@>]*)\.@(?<Token>[\w\W][^\.@]*)",
                                 "href=\".@${Token}", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<style(.*?)>(.*?)</style>", string.Empty, RegexOptions.IgnoreCase | RegexOptions.Singleline);

            //Correction pour les ancres - voir Bug ID:  3624 
            result = Regex.Replace(result, @"<a\s+href=""{1}/medianamik/(?<crap>.*?)\#{1}(?<anchor>.*?)""{1}(?<rest>.*?)(?<end></a>?)",
                                 "<a href=\"#${anchor}\"${rest}${end}", RegexOptions.IgnoreCase);

            return result;
        }
    }
}
